﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Elsa.Mediator.HostedServices;
using Elsa.Workflows;
using Elsa.Workflows.Memory;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using T.FAS.Runtime.MF.Activities.Extensions;
using T.FAS.Runtime.MF.Entity;
using T.FAS.Runtime.MF.Entity.ElsaEntity;
using T.FAS.Runtime.MF.SPI;

namespace T.FAS.Runtime.MF.Activities.ActivityInputOutput
{
    public class FasCodeActivityExecuteDetailHandler<T> : AbsActivityExecuteDetailHandler where T : FASCodeActivity<object>
    {
        public FasCodeActivityExecuteDetailHandler(
           IActivity activity,
           ActivityExecutionRecord activityExecutionRecord,
           IEnumerable<ResolvedVariable> runtimeVariables,
           WorkflowInstance workflowInstance) : base(activity, activityExecutionRecord, runtimeVariables, workflowInstance)
        {

        }

        public override WorkflowInstanceDetail GetInputOutput()
        {
            var inputs = new Dictionary<string, object>();
            var outputs = new Dictionary<string, object>();
            var detail = new WorkflowInstanceDetail();

            var startActivity = Activity as JavaScriptActivity;
            if (!string.IsNullOrEmpty(ActivityExecutionRecord.SerializedActivityState))
            {
                var javaScriptActivity = JsonConvert.DeserializeObject<T>(ActivityExecutionRecord.SerializedActivityState);
                var activityInputInstanceValueDic = javaScriptActivity.InputInstanceValues ?? new Dictionary<string, object>();
                if (activityInputInstanceValueDic.ContainsKey(ActivityExecutionRecord.Id))
                {
                    var activityInstanceValues = activityInputInstanceValueDic[ActivityExecutionRecord.Id];
                    if (typeof(JObject) == activityInstanceValues.GetType())
                    {
                        var value = JArrayExtensions.ConvertJToken(activityInstanceValues as JObject);
                        var dicValues = value as Dictionary<string, object>;
                        foreach (var param in dicValues)
                        {
                            inputs.Add(param.Key, param.Value);
                        }
                    }
                    else
                    {
                        if (activityInstanceValues != null)
                        {
                            var dicValues = activityInstanceValues as Dictionary<string, object>;
                            foreach (var param in dicValues)
                            {
                                inputs.Add(param.Key, param.Value);
                            }
                        }
                    }

                }

                var activityOutputInstanceValueDic = javaScriptActivity.OutputInstanceValues ?? new Dictionary<string, object>();

                if (activityOutputInstanceValueDic.ContainsKey(ActivityExecutionRecord.Id))
                {
                    var activityOutputInstanceValues = activityOutputInstanceValueDic[ActivityExecutionRecord.Id];
                    if (typeof(JObject) == activityOutputInstanceValues.GetType())
                    {
                        var value = JArrayExtensions.ConvertJToken(activityOutputInstanceValues as JObject);
                        var dicValues = value as Dictionary<string, object>;
                        foreach (var variable in dicValues)
                        {
                            outputs.Add(variable.Key, variable.Value);
                        }
                    }
                    else
                    {
                        if (activityOutputInstanceValues != null)
                        {
                            var dicValues = activityOutputInstanceValues as Dictionary<string, object>;
                            foreach (var variable in dicValues)
                            {
                                outputs.Add(variable.Key, variable.Value);
                            }
                        }
                    }
                }
            }
            detail.Inputs = inputs;
            detail.Outputs = outputs;
            return detail;

        }
    }
}
